Solves for the harmonic constants for a tidal time series
arguments.py
: load the nodal corrections for tidal constituentsastro.py
: computes the basic astronomical mean longitudescrs.py
: Coordinate Reference System (CRS) routinesio.model.py
: retrieves tide model parameters for named tide modelsio.OTIS.py
: extract tidal harmonic constants from OTIS tide modelsio.ATLAS.py
: extract tidal harmonic constants from ATLAS netCDF4 tide modelsio.GOT.py
: extract tidal harmonic constants from GOT tide modelsio.FES.py
: extract tidal harmonic constants from FES tide modelsio.constituents.py
: basic tide model constituent classpredict.py
: predict tidal values using harmonic constantssolve.py
: estimates the harmonic constants for ocean tidestime.py
: utilities for calculating time operationsutilities.py
: download and management utilities for filesThis notebook uses Jupyter widgets to set parameters for calculating the tidal maps.
from __future__ import print_function
import os
import numpy as np
import matplotlib.pyplot as plt
import IPython.display
import ipywidgets
# import tide programs
import pyTMD.io
import pyTMD.time
import pyTMD.predict
import pyTMD.solve
import pyTMD.tools
import pyTMD.utilities
# autoreload
%load_ext autoreload
%autoreload 2
# available model list
model_list = sorted(pyTMD.io.model.ocean_elevation())
# display widgets for setting directory and model
TMDwidgets = pyTMD.tools.widgets()
TMDwidgets.model.options = model_list
TMDwidgets.model.value = 'GOT4.10'
TMDwidgets.VBox([
TMDwidgets.directory,
TMDwidgets.model,
TMDwidgets.atlas,
TMDwidgets.compress,
])
# default coordinates to use
LAT,LON = (-76.0, -40.0)
m = pyTMD.tools.leaflet(center=(LAT,LON), zoom=3,
zoom_control=True, marker_control=True)
# show map
m.map
table = ipywidgets.HTML()
display(table)
# get model parameters
model = pyTMD.io.model(TMDwidgets.directory.value,
format=TMDwidgets.atlas.value,
compressed=TMDwidgets.compress.value
).elevation(TMDwidgets.model.value)
# convert time to days relative to Jan 1, 1992 (48622 MJD)
minutes = np.arange(366*1440)
tide_time = pyTMD.time.convert_calendar_dates(2000, 1, 1, minute=minutes)
# delta time (TT - UT1) file
delta_file = pyTMD.utilities.get_data_path(['data','merged_deltat.data'])
# read tidal constants and interpolate to leaflet points
if model.format in ('OTIS','ATLAS','TMD3'):
constituents = pyTMD.io.OTIS.read_constants(
model.grid_file, model.model_file,
model.projection, type=model.type,
grid=model.format)
c = constituents.fields
DELTAT = np.zeros_like(tide_time)
elif (model.format == 'netcdf'):
constituents = pyTMD.io.ATLAS.read_constants(
model.grid_file, model.model_file,
type=model.type, compressed=model.compressed)
c = constituents.fields
DELTAT = np.zeros_like(tide_time)
elif (model.format == 'GOT'):
constituents = pyTMD.io.GOT.read_constants(
model.model_file, compressed=model.compressed)
c = constituents.fields
# interpolate delta times from calendar dates to tide time
DELTAT = pyTMD.time.interpolate_delta_time(delta_file, tide_time)
elif (model.format == 'FES'):
constituents = pyTMD.io.FES.read_constants(model.model_file,
type=model.type, version=model.version,
compressed=model.compressed)
c = model.constituents
# interpolate delta times from calendar dates to tide time
DELTAT = pyTMD.time.interpolate_delta_time(delta_file, tide_time)
# update the tide solution
def update_tide_solution(*args):
# leaflet location
LAT,LON = np.copy(m.marker.location)
# verify longitudes
LON = m.wrap_longitudes(LON)
if model.format in ('OTIS','ATLAS','TMD3'):
amp,ph,D = pyTMD.io.OTIS.interpolate_constants(
np.atleast_1d(LON), np.atleast_1d(LAT),
constituents, model.projection, type=model.type,
method='spline', extrapolate=True)
elif (model.format == 'netcdf'):
amp,ph,D = pyTMD.io.ATLAS.interpolate_constants(
np.atleast_1d(LON), np.atleast_1d(LAT),
constituents, type=model.type, scale=model.scale,
method='spline', extrapolate=True)
elif (model.format == 'GOT'):
amp,ph = pyTMD.io.GOT.interpolate_constants(
np.atleast_1d(LON), np.atleast_1d(LAT),
constituents, scale=model.scale,
method='spline', extrapolate=True)
elif (model.format == 'FES'):
amp,ph = pyTMD.io.FES.interpolate_constants(
np.atleast_1d(LON), np.atleast_1d(LAT),
constituents, scale=model.scale,
method='spline', extrapolate=True)
# calculate complex phase in radians for Euler's
cph = -1j*ph*np.pi/180.0
# calculate constituent oscillation
hc = amp*np.exp(cph)
# predict tidal elevations at time 1 and infer minor corrections
TIDE = pyTMD.predict.time_series(tide_time, hc, c,
deltat=DELTAT, corrections=model.format)
MINOR = pyTMD.predict.infer_minor(tide_time, hc, c,
deltat=DELTAT, corrections=model.format)
TIDE.data[:] += MINOR.data[:]
# solve for harmonic constants
famp, fph = pyTMD.solve.constants(tide_time, TIDE.data, c,
deltat=DELTAT, corrections=model.format)
# create a HTML table with values
# HTML table header
table.value = """<table>
<thead>
<tr>
<th style="text-align:center; padding: 10px">Constituent</th>
<th style="text-align:center; padding: 10px">Original Amplitude</th>
<th style="text-align:center; padding: 10px">Original Phase</th>
<th style="text-align:center; padding: 10px">Solution Amplitude</th>
<th style="text-align:center; padding: 10px">Solution Phase</th>
</tr>
</thead>
<tbody>
"""
# print the original and solution amplitudes and phases to table
for i,con in enumerate(c):
table.value += f"""
<tr>
<td style="text-align:center">{con}</td>
<td style="text-align:center">{100*amp.data[0,i]:0.1f}cm</td>
<td style="text-align:center">{ph.data[0,i]:0.1f}\u00b0</td>
<td style="text-align:center">{100*famp[i]:0.1f}cm</td>
<td style="text-align:center">{fph[i]:0.1f}\u00b0</td>
</tr>
"""
# close HTML table
table.value += """
</tbody>
</table>
"""
# run tide prediction and solution at initial location
update_tide_solution()
# watch marker location for changes
m.marker_text.observe(update_tide_solution)